package org.kgduyjj.toolbox.builder;

import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.kgduyjj.toolbox.exception.VelocityException;

/**
 * Velocity模版工具
 * 
 * @author K.y
 * @since 2017-11-28
 * @version Alpha-1.42
 *
 */
public class VelocityBuilder {
	private static final String CLASS_RES_LOADER_KEY = "file.resource.loader.class";
	private static final String CLASS_RES_LOADER_VALUE = "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader";
	private static final String DEFAULT_TEMPLATE_PACKAGE = "template";
	private String templatePackage;
	private static VelocityEngine ve;
	private static Properties properties;
	private static Template template;
	private static VelocityContext context;
	private static Writer wt;

	/**
	 * 构建VM模版工具
	 * 
	 * @param templatePackage
	 */
	public VelocityBuilder(String templatePackage) {
		super();
		if (!StringUtils.isBlank(templatePackage)) {
			this.templatePackage = templatePackage;
		} else {
			templatePackage = DEFAULT_TEMPLATE_PACKAGE;
		}
	}

	public String exportString(Map<String, Object> resultMap, String tempFile, String tempFileName) throws Exception {
		ve = new VelocityEngine();
		properties = new Properties();
		// 取得vm模版路径
		properties.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, tempFile);
		// 初始化properties
		ve.init(properties);
		// 取得vm模版/vm模版上下文
		template = ve.getTemplate(tempFileName, "UTF-8");
		context = new VelocityContext();
		context.put("dateTool", new DateTool());
		context.put("numberTool", new NumberTool());
		for (Object key : resultMap.keySet()) {
			context.put(key.toString(), resultMap.get(key));
		}
		StringWriter w = new StringWriter();
		template.merge(context, w);
		return w.toString();
	}

	/**
	 * 转换模版为常规文本
	 * 
	 * @param tempName
	 * @param objs
	 * @return
	 * @throws Exception
	 */
	public String templateToText(String tempName, Object... objs) throws Exception {
		if (objs != null && objs.length % 2 != 0) {
			throw new VelocityException("参数错误[无法构建为配对参数对象]");
		}
		Properties p = new Properties();
		p.put(CLASS_RES_LOADER_KEY, CLASS_RES_LOADER_VALUE);
		Velocity.init(p);
		context = new VelocityContext();
		for (int i = 0; i < objs.length; i = i + 2) {
			context.put((String) objs[i], objs[i + 1]);
		}
		template = Velocity.getTemplate(templatePackage + "/" + tempName + ".vm", "UTF-8");
		wt = new StringWriter();
		template.merge(context, wt);
		return wt.toString();
	}

	/**
	 * 转换模版为常规文本
	 * 
	 * @param tempName
	 * @param objs
	 * @return
	 * @throws Exception
	 */
	public String templateToText(String tempName, Map<String, Object> values) throws Exception {
		Properties p = new Properties();
		p.put(CLASS_RES_LOADER_KEY, CLASS_RES_LOADER_VALUE);
		Velocity.init(p);
		context = new VelocityContext();
		if (!values.isEmpty()) {
			for (String key : values.keySet()) {
				context.put(key, values.get(key));
			}
		}
		template = Velocity.getTemplate(templatePackage + "/" + tempName + ".vm", "UTF-8");
		wt = new StringWriter();
		template.merge(context, wt);
		return wt.toString();
	}
}
